// Copyright (c) 2021 Presto Labs Pte. Ltd.
// Author: hyuan

#pragma once

#include <string>

#include <rapidjson/document.h>

#include "coin/proto/coin_query.pb.h"

namespace coin2::exchange::kucoin::order_v1 {

namespace error_code {

inline int32_t GetErrorCodeAsInt(
    const rapidjson::GenericValue<rapidjson::UTF8<>>& json_error_code) {
  int32_t error_code = 0;
  if (json_error_code.IsInt()) {
    error_code = json_error_code.GetInt();
  } else if (json_error_code.IsString() && std::strlen(json_error_code.GetString()) > 0) {
    error_code = std::stoi(json_error_code.GetString());
  }
  return error_code;
}

inline std::string GetExchangeOrderErrorCode(
    const rapidjson::GenericValue<rapidjson::UTF8<>>& json) {
  if (json.HasMember("code")) {
    return std::to_string(GetErrorCodeAsInt(json["code"]));
  } else {
    return {};
  }
}

inline std::string GetExchangeOrderErrorMsg(
    const rapidjson::GenericValue<rapidjson::UTF8<>>& json) {
  if (json.HasMember("msg")) {
    return json["msg"].GetString();
  } else {
    return {};
  }
}

inline coin::proto::OrderErrorCode GetOrderErrorCode(
    const rapidjson::GenericValue<rapidjson::UTF8<>>& json_error_code,
    const rapidjson::GenericValue<rapidjson::UTF8<>>& json_error_msg) {
  using coin::proto::OrderErrorCode;
  auto result = coin::proto::OrderErrorCode::ORDER_UNKNOWN_ERROR;
  int32_t error_code = GetErrorCodeAsInt(json_error_code);
  std::string error_msg = json_error_msg.GetString();

  if (error_code == 200000) {
    if (!error_msg.empty() && error_msg == "account service error, return no result") {
      result = OrderErrorCode::ORDER_UNCERTAIN;
    } else {
      result = OrderErrorCode::ORDER_NO_ERROR;
    }
  } else if (error_code == 200004) {
    result = OrderErrorCode::SUBMIT_ORDER_INSUFFICIENT_FUND;
  } else if (error_code == 408000 && error_msg == "request timeout") {
    result = OrderErrorCode::ORDER_UNCERTAIN;
  }

  return result;
}

}  // namespace error_code

}  // namespace coin2::exchange::kucoin::order_v1
